Assignment Objectives

  • Understand the theoretical basis of Bootstrap sampling methods for approximating sampling distributions.

  • Assess the performance of Bootstrap sampling distributions against exact and asymptotic sampling distributions.

  • Implement Bootstrap sampling algorithm and construct sampling distributions using R.


Question 1: Asymptotic vs Bootstrap Sampling Distributions

Write an essay summarizing the concepts of Asymptotic and Bootstrap Sampling Distributions, along with their key applications. Your discussion should be grounded in your personal understanding of the material. Any external sources including AI tools consulted must be clearly cited.

Essay Prompt: Discuss the concepts of the bootstrap sampling plan, the bootstrap sampling distribution, and the asymptotic sampling distribution in the context of statistics (e.g., sample mean and variance) computed from an independent and identically distributed (i.i.d.) sample. Your discussion should:

  • Clearly outline the key assumptions required for each method.

  • Explain the practical application of each distribution.

  • Provide guidance on when and why one should be preferred over the other in statistical inference.

Asymptotic Sampling Distributions

An asymptotic sampling distribution refers to what happens to a statistic’s sampling distribution as the sample size \(n \to \infty\). In other words, if you repeatedly take samples of size n and compute a statistic each time, the distribution of that statistic will approach a specific limiting distribution as n becomes very large.

The most common example is the sample mean. Suppose we have observations \(X_1, X_2, \ldots, X_n\) that are independent and identically distributed (i.i.d.) from some population with mean \(\mu\) and variance \(\sigma^2\). Then by the Central Limit Theorem, \[ \bar{X} \to N\left(\mu, \frac{\sigma}{\sqrt{n}}\right) \quad \text{as } n \to \infty \] The assumptions here are:

  • The observations must be independent.

  • The observations must be identically distributed.

  • The population must have a finite mean and finite variance.

  • The sample size must be sufficiently large for the normal approximation to be accurate.

This is extremely useful because once we know the distribution of the statistic, we can use it to construct confidence intervals, perform hypothesis tests, and compute probabilities.

There are similar asymptotic results for other statistics. For example, the sample proportion, when based on independent Bernoulli trials with probability of success p, follows: \[ \hat{p} \stackrel{d}{\sim} N\left(p, \frac{p(1-p)}{n}\right) \quad \text{for large } n \] The assumptions for this result are:

  • The trials are independent.

  • Each trial has the same probability of success p.

  • Both np and n(1−p) are sufficiently large to justify the normal approximation.

There is also an asymptotic result for sample variance. When sample size n is large, the sample variance \(S^2\) is approximately normally distributed as \[ S^2 \stackrel{d}{\to} N\left(\sigma^2, \frac{\mu_4 - \sigma^4}{n}\right) \quad \text{as } n \to \infty, \] Overall, asymptotic sample distributions help us better understand statistics as sample size grows and provide an easy way to perform statistical inference when exact distributions are hard to come by.

Bootstrap Sampling Distributions

Asymptotic theory proves that a statistic follows a certain distribution when n is large. But what if n is not large? Or what if your statistic is something like the median, a percentile, or some other statistic where there is no simple formula? This is where bootstrap sampling comes into play.

Bootstrap sampling is used to approximate the sampling distribution of a statistic with fewer assumptions. Bootstrap actually uses the data itself to estimate the distribution. Suppose you observe a sample: \(X_1, X_2, \ldots, X_n\). You first compute whatever statistic you are interested in. Then you repeatedly draw n observations at random with replacement from the original sample. Each resample forms a new “bootstrap sample.” For each bootstrap sample, you recompute the statistic. After repeating this process many times (often thousands), you obtain a distribution of bootstrap statistics. This empirical distribution is then used as an approximation to the statistic’s true sampling distribution.

Bootstrap assumes the sample is representative of the population. If the sample is biased so will the bootstrap. Once again, observations must be independent and identically distributed. The sample size must be sufficiently large, if you have an extremely small n it won’t represent the population well. Bootstrap distributions can be used for the same inferences as asymptotic distributions (CIs, Hypothesis Tests, etc.).

You commonly use bootstrap when working with smaller sample sizes or complex statistics where the sampling distribution is unknown or difficult to derive. You also use bootstrap when trying to understand how much your statistic would fluctuate from sample to sample. Since you repeatedly compute the statistic on many re-sampled datasets, the standard deviation of the bootstrap statistics provides an estimate of the statistic’s variability. This value is interpreted as the bootstrap estimate of the standard error, which tells you how stable your statistic is.

Overall, both asymptotic and bootstrap methods approximate the sampling distribution of a statistic in order to perform inference. Asymptotic methods rely on theoretical large sample results, while bootstrap methods rely on resampling from observed data. Each approach has its advantages, and understanding their assumptions allows us to choose the appropriate method for a given statistical problem.

Question 2: Daily Coffee Sales (in mL) at Two Different Cafe Locations

This data set represents the volume of regular brewed coffee sold per day (in milliliters) at two different cafe locations over a period of 50 days.

2850, 3200, 2900, 3100, 2950, 7800, 8100, 7900, 3300, 3050, 4000, 4200, 3150, 3400, 7700, 8200, 
3250, 4400, 3100, 4200, 4500, 4800, 4300, 8500, 8200, 8900, 8700, 3250, 3000, 4600, 4100, 8400, 
8800, 3350, 4700, 3100, 8100, 3050, 8300, 4100, 3100, 8300, 8900, 8200, 4400, 4500, 3250, 4600, 
8400, 3300, 4200, 4500, 4800, 4300, 8500

We are interested in finding the sampling distribution of sample means that will be used for various inferences about the underlying population mean.

  1. Based on the given data, can the Central Limit Theorem be used to derive the asymptotic sampling distribution of the sample mean? Justify your answer.

The Central Limit Theorem states: the sampling distribution of the sample mean becomes approximately normal as sample size becomes large, regardless of the population’s distribution. We don’t know the population’s distribution which is fine. We know we have a sample size of n = 55 which is large enough. However, the data must be independent and identically distributed. The prompt says each value represents the amount of coffee sold per day at two different cafe locations over a period of 50 days, yet we have 55 observations. If there are two cafes, that means some observations come from one distribution and others from a different distribution? This means the data isn’t identically distributed. If each observation was a combination of sales, than the data would be identically distributed. For the sake of the problem, I’m going to assume the second case, and therefore we can use the Central Limit Theorem to derive the asymptotic sampling distribution of the sample mean.

  1. Apply the bootstrap method to estimate the sampling distribution (often called the bootstrap sampling distribution) of the sample mean. Generate a kernel density estimate from the bootstrap sample means and plot it. Then, use this bootstrap distribution to validate your conclusion from part (a). Make sure your visuals are effective in enhancing the presentation of these results.
data <- c(2850, 3200, 2900, 3100, 2950, 7800, 8100, 7900, 3300, 3050, 4000, 4200, 3150, 3400, 7700, 8200, 
3250, 4400, 3100, 4200, 4500, 4800, 4300, 8500, 8200, 8900, 8700, 3250, 3000, 4600, 4100, 8400, 
8800, 3350, 4700, 3100, 8100, 3050, 8300, 4100, 3100, 8300, 8900, 8200, 4400, 4500, 3250, 4600, 
8400, 3300, 4200, 4500, 4800, 4300, 8500)

bootstrap <- function (data, statistic, B){ #function takes in the data, a function to calculate the stat, and the number of resamples
  n <- length(data)
  stats <- numeric(B)
  for (i in 1:B){
    new_data <- sample(data, n, replace = TRUE) #new random sample with replacement
    stats[[i]] <- statistic(new_data) #calculate stat from new sample and add it to list
  }
  return(stats)
}
  
statistic <- function (data){
  mean(data)
}

stats <- bootstrap(data, statistic, 5000) #get 5000 sample means using bootstrap method

F_r <- density(stats) #calculating densities

plot_df <- data.frame(
  t = F_r$x,
  Boot = F_r$y
)

muhat <- mean(data)
sehat <- sd(data) / sqrt(length(data))

plot_df$Asymptotic <- dnorm(plot_df$t, mean = muhat, sd = sehat) #adding the asymptotic sampling distribution

kde_plt <- ggplot(plot_df, aes(x = t)) +
  geom_line(aes(y = Asymptotic, color = "Asymptotic"), linewidth = 1, linetype = "dashed") +
  geom_line(aes(y = Boot, color = "Bootstrap"), linewidth = 1) +
  labs(
    title = "Bootstrap vs Asymptotic Sampling Distribution (Mean)",
    x = "t",
    y = "Density"
  ) +
  scale_color_manual(values = c("red", "blue")) +
  theme(plot.title = element_text(hjust = 0.5))

ggplotly(kde_plt)

The KDE of the bootstrap sample means appears symmetric and uni-modal, suggesting that the sampling distribution of the mean is approximately normal. The distribution using the bootstrap method is nearly identical to the asymptotic distribution. Therefore, using the Central Limit Theorem to derive the asymptotic sampling distribution of the sample mean would’ve been acceptable.

  1. Repeat the analysis in parts (a) and (b) for the sample variance.

The Central Limit Theorem for variance states that for a sufficiently large sample size, which we have, the sample distribution of the sample variance approaches a normal distribution. Since the data is i.i.d, the CLT should be applicable.

data <- c(2850, 3200, 2900, 3100, 2950, 7800, 8100, 7900, 3300, 3050, 4000, 4200, 3150, 3400, 7700, 8200, 
3250, 4400, 3100, 4200, 4500, 4800, 4300, 8500, 8200, 8900, 8700, 3250, 3000, 4600, 4100, 8400, 
8800, 3350, 4700, 3100, 8100, 3050, 8300, 4100, 3100, 8300, 8900, 8200, 4400, 4500, 3250, 4600, 
8400, 3300, 4200, 4500, 4800, 4300, 8500)

bootstrap <- function (data, statistic, B){
  n <- length(data)
  stats <- numeric(B)
  for (i in 1:B){
    new_data <- sample(data, n, replace = TRUE)
    stats[[i]] <- statistic(new_data)
  }
  return(stats)
}
  
statistic <- function (data){ #same code change statistic to variance
  var(data)
}

stats <- bootstrap(data, statistic, 5000)

F_r <- density(stats)

plot_df <- data.frame(
  t = F_r$x,
  R_density = F_r$y
)

kde_plt <- ggplot(plot_df, aes(x = t, y = R_density)) +
  geom_line(linewidth = 1) +
  labs(
    title = "Bootstrap Sample Variance KDE",
    x = "t",
    y = "Density"
  ) +
  theme(plot.title = element_text(hjust = 0.5))

ggplotly(kde_plt)

The KDE of the bootstrap sample variances appears symmetric and uni-modal, suggesting that the sampling distribution of the variance is approximately normal. Therefore, using the Central Limit Theorem to derive the asymptotic sampling distribution of the sample variance would’ve been acceptable.

LS0tCnRpdGxlOiAiQXNzaWdubWVudCAzOiBFQ0RGIGFuZCBCb290c3RyYXAgU2FtcGxpbmcgYW5kIEFwcGxpY2F0aW9ucyIKYXV0aG9yOiAiQ2hhcmxpZSBNb3JnYW4iCmRhdGU6ICIgRHVlOiAwMi8xNi8yNiIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6IAogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogNAogICAgdG9jX2Zsb2F0OiB5ZXMKICAgIG51bWJlcl9zZWN0aW9uczogbm8KICAgIHRvY19jb2xsYXBzZWQ6IHllcwogICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMKICAgIHNtb290aF9zY3JvbGw6IHllcwogICAgdGhlbWU6IGx1bWVuCiAgcGRmX2RvY3VtZW50OiAKICAgIHRvYzogeWVzCiAgICB0b2NfZGVwdGg6IDQKICAgIGZpZ19jYXB0aW9uOiB5ZXMKICAgIG51bWJlcl9zZWN0aW9uczogeWVzCiAgICBmaWdfd2lkdGg6IDMKICAgIGZpZ19oZWlnaHQ6IDMKICB3b3JkX2RvY3VtZW50OiAKICAgIHRvYzogeWVzCiAgICB0b2NfZGVwdGg6IDQKICAgIGZpZ19jYXB0aW9uOiB5ZXMKICAgIGtlZXBfbWQ6IHllcwplZGl0b3Jfb3B0aW9uczogCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQotLS0KCmBgYHtjc3MsIGVjaG8gPSBGQUxTRX0KI1RPQzo6YmVmb3JlIHsKICBjb250ZW50OiAiVGFibGUgb2YgQ29udGVudHMiOwogIGZvbnQtd2VpZ2h0OiBib2xkOwogIGZvbnQtc2l6ZTogMS4yZW07CiAgZGlzcGxheTogYmxvY2s7CiAgY29sb3I6IG5hdnk7CiAgbWFyZ2luLWJvdHRvbTogMTBweDsKfQoKCmRpdiNUT0MgbGkgeyAgICAgLyogdGFibGUgb2YgY29udGVudCAgKi8KICAgIGxpc3Qtc3R5bGU6dXBwZXItcm9tYW47CiAgICBiYWNrZ3JvdW5kLWltYWdlOm5vbmU7CiAgICBiYWNrZ3JvdW5kLXJlcGVhdDpub25lOwogICAgYmFja2dyb3VuZC1wb3NpdGlvbjowOwp9CgpoMS50aXRsZSB7ICAgIC8qIGxldmVsIDEgaGVhZGVyIG9mIHRpdGxlICAqLwogIGZvbnQtc2l6ZTogMjJweDsKICBmb250LXdlaWdodDogYm9sZDsKICBjb2xvcjogRGFya1JlZDsKICB0ZXh0LWFsaWduOiBjZW50ZXI7CiAgZm9udC1mYW1pbHk6ICJHaWxsIFNhbnMiLCBzYW5zLXNlcmlmOwp9CgpoNC5hdXRob3IgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLwogIGZvbnQtc2l6ZTogMTVweDsKICBmb250LXdlaWdodDogYm9sZDsKICBmb250LWZhbWlseTogc3lzdGVtLXVpOwogIGNvbG9yOiBuYXZ5OwogIHRleHQtYWxpZ246IGNlbnRlcjsKfQoKaDQuZGF0ZSB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovCiAgZm9udC1zaXplOiAxOHB4OwogIGZvbnQtd2VpZ2h0OiBib2xkOwogIGZvbnQtZmFtaWx5OiAiR2lsbCBTYW5zIiwgc2Fucy1zZXJpZjsKICBjb2xvcjogRGFya0JsdWU7CiAgdGV4dC1hbGlnbjogY2VudGVyOwp9CgpoMSB7IC8qIEhlYWRlciAxIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovCiAgICBmb250LXNpemU6IDIwcHg7CiAgICBmb250LXdlaWdodDogYm9sZDsKICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOwogICAgY29sb3I6IGRhcmtyZWQ7CiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7Cn0KCmgyIHsgLyogSGVhZGVyIDIgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8KICAgIGZvbnQtc2l6ZTogMThweDsKICAgIGZvbnQtd2VpZ2h0OiBib2xkOwogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7CiAgICBjb2xvcjogbmF2eTsKICAgIHRleHQtYWxpZ246IGxlZnQ7Cn0KCmgzIHsgLyogSGVhZGVyIDMgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8KICAgIGZvbnQtc2l6ZTogMTZweDsKICAgIGZvbnQtd2VpZ2h0OiBib2xkOwogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7CiAgICBjb2xvcjogbmF2eTsKICAgIHRleHQtYWxpZ246IGxlZnQ7Cn0KCmg0IHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8KICAgIGZvbnQtc2l6ZTogMTRweDsKICBmb250LXdlaWdodDogYm9sZDsKICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOwogICAgY29sb3I6IGRhcmtyZWQ7CiAgICB0ZXh0LWFsaWduOiBsZWZ0Owp9CgovKiBBZGQgZG90cyBhZnRlciBudW1iZXJlZCBoZWFkZXJzICovCi5oZWFkZXItc2VjdGlvbi1udW1iZXI6OmFmdGVyIHsKICBjb250ZW50OiAiLiI7Cgpib2R5IHsgYmFja2dyb3VuZC1jb2xvcjp3aGl0ZTsgfQoKLmhpZ2hsaWdodG1lIHsgYmFja2dyb3VuZC1jb2xvcjp5ZWxsb3c7IH0KCnAgeyBiYWNrZ3JvdW5kLWNvbG9yOndoaXRlOyB9Cgp9CmBgYAoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CiMgY29kZSBjaHVuayBzcGVjaWZpZXMgd2hldGhlciB0aGUgUiBjb2RlLCB3YXJuaW5ncywgYW5kIG91dHB1dCAKIyB3aWxsIGJlIGluY2x1ZGVkIGluIHRoZSBvdXRwdXQgZmlsZXMuCmlmICghcmVxdWlyZSgia25pdHIiKSkgewogICBpbnN0YWxsLnBhY2thZ2VzKCJrbml0ciIpCiAgIGxpYnJhcnkoa25pdHIpCn0KaWYgKCFyZXF1aXJlKCJwYW5kZXIiKSkgewogICBpbnN0YWxsLnBhY2thZ2VzKCJwYW5kZXIiKQogICBsaWJyYXJ5KHBhbmRlcikKfQppZiAoIXJlcXVpcmUoImdncGxvdDIiKSkgewogIGluc3RhbGwucGFja2FnZXMoImdncGxvdDIiKQogIGxpYnJhcnkoZ2dwbG90MikKfQppZiAoIXJlcXVpcmUoInRpZHl2ZXJzZSIpKSB7CiAgaW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIikKICBsaWJyYXJ5KHRpZHl2ZXJzZSkKfQoKaWYgKCFyZXF1aXJlKCJwbG90bHkiKSkgewogIGluc3RhbGwucGFja2FnZXMoInBsb3RseSIpCiAgbGlicmFyeShwbG90bHkpCn0KIyMjIwprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsICAgICAgICMgaW5jbHVkZSBjb2RlIGNodW5rIGluIHRoZSBvdXRwdXQgZmlsZQogICAgICAgICAgICAgICAgICAgICAgd2FybmluZyA9IEZBTFNFLCAgICMgc29tZXRpbWVzLCB5b3UgY29kZSBtYXkgcHJvZHVjZSB3YXJuaW5nIG1lc3NhZ2VzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgeW91IGNhbiBjaG9vc2UgdG8gaW5jbHVkZSB0aGUgd2FybmluZyBtZXNzYWdlcyBpbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgdGhlIG91dHB1dCBmaWxlLiAKICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMgPSBUUlVFLCAgICAjIHlvdSBjYW4gYWxzbyBkZWNpZGUgd2hldGhlciB0byBpbmNsdWRlIHRoZSBvdXRwdXQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGluIHRoZSBvdXRwdXQgZmlsZS4KICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgIGNvbW1lbnQgPSBOQQogICAgICAgICAgICAgICAgICAgICAgKSAgCmBgYAogCiBcCiAKIyMgKipBc3NpZ25tZW50IE9iamVjdGl2ZXMqKiAKCiogVW5kZXJzdGFuZCB0aGUgdGhlb3JldGljYWwgYmFzaXMgb2YgQm9vdHN0cmFwIHNhbXBsaW5nIG1ldGhvZHMgZm9yIGFwcHJveGltYXRpbmcgc2FtcGxpbmcgZGlzdHJpYnV0aW9ucy4KCiogQXNzZXNzIHRoZSBwZXJmb3JtYW5jZSBvZiBCb290c3RyYXAgc2FtcGxpbmcgZGlzdHJpYnV0aW9ucyBhZ2FpbnN0IGV4YWN0IGFuZCBhc3ltcHRvdGljIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbnMuCgoqIEltcGxlbWVudCBCb290c3RyYXAgc2FtcGxpbmcgYWxnb3JpdGhtIGFuZCBjb25zdHJ1Y3Qgc2FtcGxpbmcgZGlzdHJpYnV0aW9ucyB1c2luZyBSLgoKXAoKIyMgKipRdWVzdGlvbiAxOiBBc3ltcHRvdGljIHZzIEJvb3RzdHJhcCBTYW1wbGluZyBEaXN0cmlidXRpb25zKioKCldyaXRlIGFuIGVzc2F5IHN1bW1hcml6aW5nIHRoZSBjb25jZXB0cyBvZiBBc3ltcHRvdGljIGFuZCBCb290c3RyYXAgU2FtcGxpbmcgRGlzdHJpYnV0aW9ucywgYWxvbmcgd2l0aCB0aGVpciBrZXkgYXBwbGljYXRpb25zLiBZb3VyIGRpc2N1c3Npb24gc2hvdWxkIGJlIGdyb3VuZGVkIGluIHlvdXIgcGVyc29uYWwgdW5kZXJzdGFuZGluZyBvZiB0aGUgbWF0ZXJpYWwuIEFueSBleHRlcm5hbCBzb3VyY2VzIGluY2x1ZGluZyBBSSB0b29scyBjb25zdWx0ZWQgbXVzdCBiZSBjbGVhcmx5IGNpdGVkLiAKCgoqKkVzc2F5IFByb21wdCoqOiBEaXNjdXNzIHRoZSBjb25jZXB0cyBvZiB0aGUgYm9vdHN0cmFwIHNhbXBsaW5nIHBsYW4sIHRoZSBib290c3RyYXAgc2FtcGxpbmcgZGlzdHJpYnV0aW9uLCBhbmQgdGhlIGFzeW1wdG90aWMgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIGluIHRoZSBjb250ZXh0IG9mIHN0YXRpc3RpY3MgKGUuZy4sIHNhbXBsZSBtZWFuIGFuZCB2YXJpYW5jZSkgY29tcHV0ZWQgZnJvbSBhbiBpbmRlcGVuZGVudCBhbmQgaWRlbnRpY2FsbHkgZGlzdHJpYnV0ZWQgKGkuaS5kLikgc2FtcGxlLiBZb3VyIGRpc2N1c3Npb24gc2hvdWxkOgoKKiBDbGVhcmx5IG91dGxpbmUgdGhlIGtleSBhc3N1bXB0aW9ucyByZXF1aXJlZCBmb3IgZWFjaCBtZXRob2QuCgoqIEV4cGxhaW4gdGhlIHByYWN0aWNhbCBhcHBsaWNhdGlvbiBvZiBlYWNoIGRpc3RyaWJ1dGlvbi4KCiogUHJvdmlkZSBndWlkYW5jZSBvbiB3aGVuIGFuZCB3aHkgb25lIHNob3VsZCBiZSBwcmVmZXJyZWQgb3ZlciB0aGUgb3RoZXIgaW4gc3RhdGlzdGljYWwgaW5mZXJlbmNlLgoKIyMjIEFzeW1wdG90aWMgU2FtcGxpbmcgRGlzdHJpYnV0aW9ucwoKQW4gYXN5bXB0b3RpYyBzYW1wbGluZyBkaXN0cmlidXRpb24gcmVmZXJzIHRvIHdoYXQgaGFwcGVucyB0byBhIHN0YXRpc3RpY+KAmXMgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIGFzIHRoZSBzYW1wbGUgc2l6ZSAkbiBcdG8gXGluZnR5JC4gSW4gb3RoZXIgd29yZHMsIGlmIHlvdSByZXBlYXRlZGx5IHRha2Ugc2FtcGxlcyBvZiBzaXplIG4gYW5kIGNvbXB1dGUgYSBzdGF0aXN0aWMgZWFjaCB0aW1lLCB0aGUgZGlzdHJpYnV0aW9uIG9mIHRoYXQgc3RhdGlzdGljIHdpbGwgYXBwcm9hY2ggYSBzcGVjaWZpYyBsaW1pdGluZyBkaXN0cmlidXRpb24gYXMgbiBiZWNvbWVzIHZlcnkgbGFyZ2UuCgpUaGUgbW9zdCBjb21tb24gZXhhbXBsZSBpcyB0aGUgc2FtcGxlIG1lYW4uIFN1cHBvc2Ugd2UgaGF2ZSBvYnNlcnZhdGlvbnMgJFhfMSwgWF8yLCBcbGRvdHMsIFhfbiQgdGhhdCBhcmUgaW5kZXBlbmRlbnQgYW5kIGlkZW50aWNhbGx5IGRpc3RyaWJ1dGVkIChpLmkuZC4pIGZyb20gc29tZSBwb3B1bGF0aW9uIHdpdGggbWVhbiAkXG11JCBhbmQgdmFyaWFuY2UgJFxzaWdtYV4yJC4gVGhlbiBieSB0aGUgQ2VudHJhbCBMaW1pdCBUaGVvcmVtLCAKJCQKXGJhcntYfSBcdG8gTlxsZWZ0KFxtdSwgIFxmcmFje1xzaWdtYX17XHNxcnR7bn19XHJpZ2h0KSBccXVhZCBcdGV4dHthcyB9IG4gXHRvIFxpbmZ0eQokJApUaGUgYXNzdW1wdGlvbnMgaGVyZSBhcmU6CgoqIFRoZSBvYnNlcnZhdGlvbnMgbXVzdCBiZSBpbmRlcGVuZGVudC4KCiogVGhlIG9ic2VydmF0aW9ucyBtdXN0IGJlIGlkZW50aWNhbGx5IGRpc3RyaWJ1dGVkLgoKKiBUaGUgcG9wdWxhdGlvbiBtdXN0IGhhdmUgYSBmaW5pdGUgbWVhbiBhbmQgZmluaXRlIHZhcmlhbmNlLgoKKiBUaGUgc2FtcGxlIHNpemUgbXVzdCBiZSBzdWZmaWNpZW50bHkgbGFyZ2UgZm9yIHRoZSBub3JtYWwgYXBwcm94aW1hdGlvbiB0byBiZSBhY2N1cmF0ZS4KClRoaXMgaXMgZXh0cmVtZWx5IHVzZWZ1bCBiZWNhdXNlIG9uY2Ugd2Uga25vdyB0aGUgZGlzdHJpYnV0aW9uIG9mIHRoZSBzdGF0aXN0aWMsIHdlIGNhbiB1c2UgaXQgdG8gY29uc3RydWN0IGNvbmZpZGVuY2UgaW50ZXJ2YWxzLCBwZXJmb3JtIGh5cG90aGVzaXMgdGVzdHMsIGFuZCBjb21wdXRlIHByb2JhYmlsaXRpZXMuCgpUaGVyZSBhcmUgc2ltaWxhciBhc3ltcHRvdGljIHJlc3VsdHMgZm9yIG90aGVyIHN0YXRpc3RpY3MuIEZvciBleGFtcGxlLCB0aGUgc2FtcGxlIHByb3BvcnRpb24sIHdoZW4gYmFzZWQgb24gaW5kZXBlbmRlbnQgQmVybm91bGxpIHRyaWFscyB3aXRoIHByb2JhYmlsaXR5IG9mIHN1Y2Nlc3MgcCwgZm9sbG93czoKJCQKXGhhdHtwfSBcc3RhY2tyZWx7ZH17XHNpbX0gTlxsZWZ0KHAsIFxmcmFje3AoMS1wKX17bn1ccmlnaHQpIFxxdWFkIFx0ZXh0e2ZvciBsYXJnZSB9IG4KJCQKVGhlIGFzc3VtcHRpb25zIGZvciB0aGlzIHJlc3VsdCBhcmU6CgoqIFRoZSB0cmlhbHMgYXJlIGluZGVwZW5kZW50LgoKKiBFYWNoIHRyaWFsIGhhcyB0aGUgc2FtZSBwcm9iYWJpbGl0eSBvZiBzdWNjZXNzIHAuCgoqIEJvdGggbnAgYW5kIG4oMeKIknApIGFyZSBzdWZmaWNpZW50bHkgbGFyZ2UgdG8ganVzdGlmeSB0aGUgbm9ybWFsIGFwcHJveGltYXRpb24uCgpUaGVyZSBpcyBhbHNvIGFuIGFzeW1wdG90aWMgcmVzdWx0IGZvciBzYW1wbGUgdmFyaWFuY2UuIFdoZW4gc2FtcGxlIHNpemUgbiBpcyBsYXJnZSwgdGhlIHNhbXBsZSB2YXJpYW5jZSAkU14yJCBpcyBhcHByb3hpbWF0ZWx5IG5vcm1hbGx5IGRpc3RyaWJ1dGVkIGFzCiQkClNeMiBcc3RhY2tyZWx7ZH17XHRvfSBOXGxlZnQoXHNpZ21hXjIsIFxmcmFje1xtdV80IC0gXHNpZ21hXjR9e259XHJpZ2h0KSBccXVhZCBcdGV4dHthcyB9IG4gXHRvIFxpbmZ0eSwKJCQKT3ZlcmFsbCwgYXN5bXB0b3RpYyBzYW1wbGUgZGlzdHJpYnV0aW9ucyBoZWxwIHVzIGJldHRlciB1bmRlcnN0YW5kIHN0YXRpc3RpY3MgYXMgc2FtcGxlIHNpemUgZ3Jvd3MgYW5kIHByb3ZpZGUgYW4gZWFzeSB3YXkgdG8gcGVyZm9ybSBzdGF0aXN0aWNhbCBpbmZlcmVuY2Ugd2hlbiBleGFjdCBkaXN0cmlidXRpb25zIGFyZSBoYXJkIHRvIGNvbWUgYnkuCgojIyMgQm9vdHN0cmFwIFNhbXBsaW5nIERpc3RyaWJ1dGlvbnMKCkFzeW1wdG90aWMgdGhlb3J5IHByb3ZlcyB0aGF0IGEgc3RhdGlzdGljIGZvbGxvd3MgYSBjZXJ0YWluIGRpc3RyaWJ1dGlvbiB3aGVuIG4gaXMgbGFyZ2UuIEJ1dCB3aGF0IGlmIG4gaXMgbm90IGxhcmdlPyBPciB3aGF0IGlmIHlvdXIgc3RhdGlzdGljIGlzIHNvbWV0aGluZyBsaWtlIHRoZSBtZWRpYW4sIGEgcGVyY2VudGlsZSwgb3Igc29tZSBvdGhlciBzdGF0aXN0aWMgd2hlcmUgdGhlcmUgaXMgbm8gc2ltcGxlIGZvcm11bGE/IFRoaXMgaXMgd2hlcmUgYm9vdHN0cmFwIHNhbXBsaW5nIGNvbWVzIGludG8gcGxheS4KCkJvb3RzdHJhcCBzYW1wbGluZyBpcyB1c2VkIHRvIGFwcHJveGltYXRlIHRoZSBzYW1wbGluZyBkaXN0cmlidXRpb24gb2YgYSBzdGF0aXN0aWMgd2l0aCBmZXdlciBhc3N1bXB0aW9ucy4gQm9vdHN0cmFwIGFjdHVhbGx5IHVzZXMgdGhlIGRhdGEgaXRzZWxmIHRvIGVzdGltYXRlIHRoZSBkaXN0cmlidXRpb24uIFN1cHBvc2UgeW91IG9ic2VydmUgYSBzYW1wbGU6ICRYXzEsIFhfMiwgXGxkb3RzLCBYX24kLiBZb3UgZmlyc3QgY29tcHV0ZSB3aGF0ZXZlciBzdGF0aXN0aWMgeW91IGFyZSBpbnRlcmVzdGVkIGluLiBUaGVuIHlvdSByZXBlYXRlZGx5IGRyYXcgbiBvYnNlcnZhdGlvbnMgYXQgcmFuZG9tIHdpdGggcmVwbGFjZW1lbnQgZnJvbSB0aGUgb3JpZ2luYWwgc2FtcGxlLiBFYWNoIHJlc2FtcGxlIGZvcm1zIGEgbmV3IOKAnGJvb3RzdHJhcCBzYW1wbGUu4oCdIEZvciBlYWNoIGJvb3RzdHJhcCBzYW1wbGUsIHlvdSByZWNvbXB1dGUgdGhlIHN0YXRpc3RpYy4gQWZ0ZXIgcmVwZWF0aW5nIHRoaXMgcHJvY2VzcyBtYW55IHRpbWVzIChvZnRlbiB0aG91c2FuZHMpLCB5b3Ugb2J0YWluIGEgZGlzdHJpYnV0aW9uIG9mIGJvb3RzdHJhcCBzdGF0aXN0aWNzLiBUaGlzIGVtcGlyaWNhbCBkaXN0cmlidXRpb24gaXMgdGhlbiB1c2VkIGFzIGFuIGFwcHJveGltYXRpb24gdG8gdGhlIHN0YXRpc3RpY+KAmXMgdHJ1ZSBzYW1wbGluZyBkaXN0cmlidXRpb24uCgpCb290c3RyYXAgYXNzdW1lcyB0aGUgc2FtcGxlIGlzIHJlcHJlc2VudGF0aXZlIG9mIHRoZSBwb3B1bGF0aW9uLiBJZiB0aGUgc2FtcGxlIGlzIGJpYXNlZCBzbyB3aWxsIHRoZSBib290c3RyYXAuIE9uY2UgYWdhaW4sIG9ic2VydmF0aW9ucyBtdXN0IGJlIGluZGVwZW5kZW50IGFuZCBpZGVudGljYWxseSBkaXN0cmlidXRlZC4gVGhlIHNhbXBsZSBzaXplIG11c3QgYmUgc3VmZmljaWVudGx5IGxhcmdlLCBpZiB5b3UgaGF2ZSBhbiBleHRyZW1lbHkgc21hbGwgbiBpdCB3b24ndCByZXByZXNlbnQgdGhlIHBvcHVsYXRpb24gd2VsbC4gQm9vdHN0cmFwIGRpc3RyaWJ1dGlvbnMgY2FuIGJlIHVzZWQgZm9yIHRoZSBzYW1lIGluZmVyZW5jZXMgYXMgYXN5bXB0b3RpYyBkaXN0cmlidXRpb25zIChDSXMsIEh5cG90aGVzaXMgVGVzdHMsIGV0Yy4pLiAKCllvdSBjb21tb25seSB1c2UgYm9vdHN0cmFwIHdoZW4gd29ya2luZyB3aXRoIHNtYWxsZXIgc2FtcGxlIHNpemVzIG9yIGNvbXBsZXggc3RhdGlzdGljcyB3aGVyZSB0aGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIGlzIHVua25vd24gb3IgZGlmZmljdWx0IHRvIGRlcml2ZS4gWW91IGFsc28gdXNlIGJvb3RzdHJhcCB3aGVuIHRyeWluZyB0byB1bmRlcnN0YW5kIGhvdyBtdWNoIHlvdXIgc3RhdGlzdGljIHdvdWxkIGZsdWN0dWF0ZSBmcm9tIHNhbXBsZSB0byBzYW1wbGUuIFNpbmNlIHlvdSByZXBlYXRlZGx5IGNvbXB1dGUgdGhlIHN0YXRpc3RpYyBvbiBtYW55IHJlLXNhbXBsZWQgZGF0YXNldHMsIHRoZSBzdGFuZGFyZCBkZXZpYXRpb24gb2YgdGhlIGJvb3RzdHJhcCBzdGF0aXN0aWNzIHByb3ZpZGVzIGFuIGVzdGltYXRlIG9mIHRoZSBzdGF0aXN0aWPigJlzIHZhcmlhYmlsaXR5LiBUaGlzIHZhbHVlIGlzIGludGVycHJldGVkIGFzIHRoZSBib290c3RyYXAgZXN0aW1hdGUgb2YgdGhlIHN0YW5kYXJkIGVycm9yLCB3aGljaCB0ZWxscyB5b3UgaG93IHN0YWJsZSB5b3VyIHN0YXRpc3RpYyBpcy4KCk92ZXJhbGwsIGJvdGggYXN5bXB0b3RpYyBhbmQgYm9vdHN0cmFwIG1ldGhvZHMgYXBwcm94aW1hdGUgdGhlIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiBvZiBhIHN0YXRpc3RpYyBpbiBvcmRlciB0byBwZXJmb3JtIGluZmVyZW5jZS4gQXN5bXB0b3RpYyBtZXRob2RzIHJlbHkgb24gdGhlb3JldGljYWwgbGFyZ2Ugc2FtcGxlIHJlc3VsdHMsIHdoaWxlIGJvb3RzdHJhcCBtZXRob2RzIHJlbHkgb24gcmVzYW1wbGluZyBmcm9tIG9ic2VydmVkIGRhdGEuIEVhY2ggYXBwcm9hY2ggaGFzIGl0cyBhZHZhbnRhZ2VzLCBhbmQgdW5kZXJzdGFuZGluZyB0aGVpciBhc3N1bXB0aW9ucyBhbGxvd3MgdXMgdG8gY2hvb3NlIHRoZSBhcHByb3ByaWF0ZSBtZXRob2QgZm9yIGEgZ2l2ZW4gc3RhdGlzdGljYWwgcHJvYmxlbS4KCiMjICoqUXVlc3Rpb24gMjogRGFpbHkgQ29mZmVlIFNhbGVzIChpbiBtTCkgYXQgVHdvIERpZmZlcmVudCBDYWZlIExvY2F0aW9ucyoqCgpUaGlzIGRhdGEgc2V0IHJlcHJlc2VudHMgdGhlIHZvbHVtZSBvZiByZWd1bGFyIGJyZXdlZCBjb2ZmZWUgc29sZCBwZXIgZGF5IChpbiBtaWxsaWxpdGVycykgYXQgdHdvIGRpZmZlcmVudCBjYWZlIGxvY2F0aW9ucyBvdmVyIGEgcGVyaW9kIG9mIDUwIGRheXMuIAoKYGBgCjI4NTAsIDMyMDAsIDI5MDAsIDMxMDAsIDI5NTAsIDc4MDAsIDgxMDAsIDc5MDAsIDMzMDAsIDMwNTAsIDQwMDAsIDQyMDAsIDMxNTAsIDM0MDAsIDc3MDAsIDgyMDAsIAozMjUwLCA0NDAwLCAzMTAwLCA0MjAwLCA0NTAwLCA0ODAwLCA0MzAwLCA4NTAwLCA4MjAwLCA4OTAwLCA4NzAwLCAzMjUwLCAzMDAwLCA0NjAwLCA0MTAwLCA4NDAwLCAKODgwMCwgMzM1MCwgNDcwMCwgMzEwMCwgODEwMCwgMzA1MCwgODMwMCwgNDEwMCwgMzEwMCwgODMwMCwgODkwMCwgODIwMCwgNDQwMCwgNDUwMCwgMzI1MCwgNDYwMCwgCjg0MDAsIDMzMDAsIDQyMDAsIDQ1MDAsIDQ4MDAsIDQzMDAsIDg1MDAKYGBgCldlIGFyZSBpbnRlcmVzdGVkIGluIGZpbmRpbmcgdGhlIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiBvZiBzYW1wbGUgbWVhbnMgdGhhdCB3aWxsIGJlIHVzZWQgZm9yIHZhcmlvdXMgaW5mZXJlbmNlcyBhYm91dCB0aGUgdW5kZXJseWluZyBwb3B1bGF0aW9uIG1lYW4uCgphKSBCYXNlZCBvbiB0aGUgZ2l2ZW4gZGF0YSwgY2FuIHRoZSBDZW50cmFsIExpbWl0IFRoZW9yZW0gYmUgdXNlZCB0byBkZXJpdmUgdGhlIGFzeW1wdG90aWMgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIHRoZSBzYW1wbGUgbWVhbj8gSnVzdGlmeSB5b3VyIGFuc3dlci4KClRoZSBDZW50cmFsIExpbWl0IFRoZW9yZW0gc3RhdGVzOiB0aGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIHRoZSBzYW1wbGUgbWVhbiBiZWNvbWVzIGFwcHJveGltYXRlbHkgbm9ybWFsIGFzIHNhbXBsZSBzaXplIGJlY29tZXMgbGFyZ2UsIHJlZ2FyZGxlc3Mgb2YgdGhlIHBvcHVsYXRpb24ncyBkaXN0cmlidXRpb24uIFdlIGRvbid0IGtub3cgdGhlIHBvcHVsYXRpb24ncyBkaXN0cmlidXRpb24gd2hpY2ggaXMgZmluZS4gV2Uga25vdyB3ZSBoYXZlIGEgc2FtcGxlIHNpemUgb2YgbiA9IDU1IHdoaWNoIGlzIGxhcmdlIGVub3VnaC4gSG93ZXZlciwgdGhlIGRhdGEgbXVzdCBiZSBpbmRlcGVuZGVudCBhbmQgaWRlbnRpY2FsbHkgZGlzdHJpYnV0ZWQuIFRoZSBwcm9tcHQgc2F5cyBlYWNoIHZhbHVlIHJlcHJlc2VudHMgdGhlIGFtb3VudCBvZiBjb2ZmZWUgc29sZCBwZXIgZGF5IGF0IHR3byBkaWZmZXJlbnQgY2FmZSBsb2NhdGlvbnMgb3ZlciBhIHBlcmlvZCBvZiA1MCBkYXlzLCB5ZXQgd2UgaGF2ZSA1NSBvYnNlcnZhdGlvbnMuIElmIHRoZXJlIGFyZSB0d28gY2FmZXMsIHRoYXQgbWVhbnMgc29tZSBvYnNlcnZhdGlvbnMgY29tZSBmcm9tIG9uZSBkaXN0cmlidXRpb24gYW5kIG90aGVycyBmcm9tIGEgZGlmZmVyZW50IGRpc3RyaWJ1dGlvbj8gVGhpcyBtZWFucyB0aGUgZGF0YSBpc24ndCBpZGVudGljYWxseSBkaXN0cmlidXRlZC4gSWYgZWFjaCBvYnNlcnZhdGlvbiB3YXMgYSBjb21iaW5hdGlvbiBvZiBzYWxlcywgdGhhbiB0aGUgZGF0YSB3b3VsZCBiZSBpZGVudGljYWxseSBkaXN0cmlidXRlZC4gRm9yIHRoZSBzYWtlIG9mIHRoZSBwcm9ibGVtLCBJJ20gZ29pbmcgdG8gYXNzdW1lIHRoZSBzZWNvbmQgY2FzZSwgYW5kIHRoZXJlZm9yZSB3ZSBjYW4gdXNlIHRoZSBDZW50cmFsIExpbWl0IFRoZW9yZW0gdG8gZGVyaXZlIHRoZSBhc3ltcHRvdGljIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiBvZiB0aGUgc2FtcGxlIG1lYW4uCgpiKSBBcHBseSB0aGUgYm9vdHN0cmFwIG1ldGhvZCB0byBlc3RpbWF0ZSB0aGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIChvZnRlbiBjYWxsZWQgdGhlIGJvb3RzdHJhcCBzYW1wbGluZyBkaXN0cmlidXRpb24pIG9mIHRoZSBzYW1wbGUgbWVhbi4gR2VuZXJhdGUgYSBrZXJuZWwgZGVuc2l0eSBlc3RpbWF0ZSBmcm9tIHRoZSBib290c3RyYXAgc2FtcGxlIG1lYW5zIGFuZCBwbG90IGl0LiBUaGVuLCB1c2UgdGhpcyBib290c3RyYXAgZGlzdHJpYnV0aW9uIHRvIHZhbGlkYXRlIHlvdXIgY29uY2x1c2lvbiBmcm9tIHBhcnQgKGEpLiBNYWtlIHN1cmUgeW91ciB2aXN1YWxzIGFyZSBlZmZlY3RpdmUgaW4gZW5oYW5jaW5nIHRoZSBwcmVzZW50YXRpb24gb2YgdGhlc2UgcmVzdWx0cy4KYGBge3J9CmRhdGEgPC0gYygyODUwLCAzMjAwLCAyOTAwLCAzMTAwLCAyOTUwLCA3ODAwLCA4MTAwLCA3OTAwLCAzMzAwLCAzMDUwLCA0MDAwLCA0MjAwLCAzMTUwLCAzNDAwLCA3NzAwLCA4MjAwLCAKMzI1MCwgNDQwMCwgMzEwMCwgNDIwMCwgNDUwMCwgNDgwMCwgNDMwMCwgODUwMCwgODIwMCwgODkwMCwgODcwMCwgMzI1MCwgMzAwMCwgNDYwMCwgNDEwMCwgODQwMCwgCjg4MDAsIDMzNTAsIDQ3MDAsIDMxMDAsIDgxMDAsIDMwNTAsIDgzMDAsIDQxMDAsIDMxMDAsIDgzMDAsIDg5MDAsIDgyMDAsIDQ0MDAsIDQ1MDAsIDMyNTAsIDQ2MDAsIAo4NDAwLCAzMzAwLCA0MjAwLCA0NTAwLCA0ODAwLCA0MzAwLCA4NTAwKQoKYm9vdHN0cmFwIDwtIGZ1bmN0aW9uIChkYXRhLCBzdGF0aXN0aWMsIEIpeyAjZnVuY3Rpb24gdGFrZXMgaW4gdGhlIGRhdGEsIGEgZnVuY3Rpb24gdG8gY2FsY3VsYXRlIHRoZSBzdGF0LCBhbmQgdGhlIG51bWJlciBvZiByZXNhbXBsZXMKICBuIDwtIGxlbmd0aChkYXRhKQogIHN0YXRzIDwtIG51bWVyaWMoQikKICBmb3IgKGkgaW4gMTpCKXsKICAgIG5ld19kYXRhIDwtIHNhbXBsZShkYXRhLCBuLCByZXBsYWNlID0gVFJVRSkgI25ldyByYW5kb20gc2FtcGxlIHdpdGggcmVwbGFjZW1lbnQKICAgIHN0YXRzW1tpXV0gPC0gc3RhdGlzdGljKG5ld19kYXRhKSAjY2FsY3VsYXRlIHN0YXQgZnJvbSBuZXcgc2FtcGxlIGFuZCBhZGQgaXQgdG8gbGlzdAogIH0KICByZXR1cm4oc3RhdHMpCn0KICAKc3RhdGlzdGljIDwtIGZ1bmN0aW9uIChkYXRhKXsKICBtZWFuKGRhdGEpCn0KCnN0YXRzIDwtIGJvb3RzdHJhcChkYXRhLCBzdGF0aXN0aWMsIDUwMDApICNnZXQgNTAwMCBzYW1wbGUgbWVhbnMgdXNpbmcgYm9vdHN0cmFwIG1ldGhvZAoKRl9yIDwtIGRlbnNpdHkoc3RhdHMpICNjYWxjdWxhdGluZyBkZW5zaXRpZXMKCnBsb3RfZGYgPC0gZGF0YS5mcmFtZSgKICB0ID0gRl9yJHgsCiAgQm9vdCA9IEZfciR5CikKCm11aGF0IDwtIG1lYW4oZGF0YSkKc2VoYXQgPC0gc2QoZGF0YSkgLyBzcXJ0KGxlbmd0aChkYXRhKSkKCnBsb3RfZGYkQXN5bXB0b3RpYyA8LSBkbm9ybShwbG90X2RmJHQsIG1lYW4gPSBtdWhhdCwgc2QgPSBzZWhhdCkgI2FkZGluZyB0aGUgYXN5bXB0b3RpYyBzYW1wbGluZyBkaXN0cmlidXRpb24KCmtkZV9wbHQgPC0gZ2dwbG90KHBsb3RfZGYsIGFlcyh4ID0gdCkpICsKICBnZW9tX2xpbmUoYWVzKHkgPSBBc3ltcHRvdGljLCBjb2xvciA9ICJBc3ltcHRvdGljIiksIGxpbmV3aWR0aCA9IDEsIGxpbmV0eXBlID0gImRhc2hlZCIpICsKICBnZW9tX2xpbmUoYWVzKHkgPSBCb290LCBjb2xvciA9ICJCb290c3RyYXAiKSwgbGluZXdpZHRoID0gMSkgKwogIGxhYnMoCiAgICB0aXRsZSA9ICJCb290c3RyYXAgdnMgQXN5bXB0b3RpYyBTYW1wbGluZyBEaXN0cmlidXRpb24gKE1lYW4pIiwKICAgIHggPSAidCIsCiAgICB5ID0gIkRlbnNpdHkiCiAgKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoInJlZCIsICJibHVlIikpICsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkKCmdncGxvdGx5KGtkZV9wbHQpCmBgYApUaGUgS0RFIG9mIHRoZSBib290c3RyYXAgc2FtcGxlIG1lYW5zIGFwcGVhcnMgc3ltbWV0cmljIGFuZCB1bmktbW9kYWwsIHN1Z2dlc3RpbmcgdGhhdCB0aGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIHRoZSBtZWFuIGlzIGFwcHJveGltYXRlbHkgbm9ybWFsLiBUaGUgZGlzdHJpYnV0aW9uIHVzaW5nIHRoZSBib290c3RyYXAgbWV0aG9kIGlzIG5lYXJseSBpZGVudGljYWwgdG8gdGhlIGFzeW1wdG90aWMgZGlzdHJpYnV0aW9uLiBUaGVyZWZvcmUsIHVzaW5nIHRoZSBDZW50cmFsIExpbWl0IFRoZW9yZW0gdG8gZGVyaXZlIHRoZSBhc3ltcHRvdGljIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiBvZiB0aGUgc2FtcGxlIG1lYW4gd291bGQndmUgYmVlbiBhY2NlcHRhYmxlLgoKYykgUmVwZWF0IHRoZSBhbmFseXNpcyBpbiBwYXJ0cyAoYSkgYW5kIChiKSBmb3IgdGhlIHNhbXBsZSB2YXJpYW5jZS4KClRoZSBDZW50cmFsIExpbWl0IFRoZW9yZW0gZm9yIHZhcmlhbmNlIHN0YXRlcyB0aGF0IGZvciBhIHN1ZmZpY2llbnRseSBsYXJnZSBzYW1wbGUgc2l6ZSwgd2hpY2ggd2UgaGF2ZSwgdGhlIHNhbXBsZSBkaXN0cmlidXRpb24gb2YgdGhlIHNhbXBsZSB2YXJpYW5jZSBhcHByb2FjaGVzIGEgbm9ybWFsIGRpc3RyaWJ1dGlvbi4gU2luY2UgdGhlIGRhdGEgaXMgaS5pLmQsIHRoZSBDTFQgc2hvdWxkIGJlIGFwcGxpY2FibGUuCmBgYHtyfQpkYXRhIDwtIGMoMjg1MCwgMzIwMCwgMjkwMCwgMzEwMCwgMjk1MCwgNzgwMCwgODEwMCwgNzkwMCwgMzMwMCwgMzA1MCwgNDAwMCwgNDIwMCwgMzE1MCwgMzQwMCwgNzcwMCwgODIwMCwgCjMyNTAsIDQ0MDAsIDMxMDAsIDQyMDAsIDQ1MDAsIDQ4MDAsIDQzMDAsIDg1MDAsIDgyMDAsIDg5MDAsIDg3MDAsIDMyNTAsIDMwMDAsIDQ2MDAsIDQxMDAsIDg0MDAsIAo4ODAwLCAzMzUwLCA0NzAwLCAzMTAwLCA4MTAwLCAzMDUwLCA4MzAwLCA0MTAwLCAzMTAwLCA4MzAwLCA4OTAwLCA4MjAwLCA0NDAwLCA0NTAwLCAzMjUwLCA0NjAwLCAKODQwMCwgMzMwMCwgNDIwMCwgNDUwMCwgNDgwMCwgNDMwMCwgODUwMCkKCmJvb3RzdHJhcCA8LSBmdW5jdGlvbiAoZGF0YSwgc3RhdGlzdGljLCBCKXsKICBuIDwtIGxlbmd0aChkYXRhKQogIHN0YXRzIDwtIG51bWVyaWMoQikKICBmb3IgKGkgaW4gMTpCKXsKICAgIG5ld19kYXRhIDwtIHNhbXBsZShkYXRhLCBuLCByZXBsYWNlID0gVFJVRSkKICAgIHN0YXRzW1tpXV0gPC0gc3RhdGlzdGljKG5ld19kYXRhKQogIH0KICByZXR1cm4oc3RhdHMpCn0KICAKc3RhdGlzdGljIDwtIGZ1bmN0aW9uIChkYXRhKXsgI3NhbWUgY29kZSBjaGFuZ2Ugc3RhdGlzdGljIHRvIHZhcmlhbmNlCiAgdmFyKGRhdGEpCn0KCnN0YXRzIDwtIGJvb3RzdHJhcChkYXRhLCBzdGF0aXN0aWMsIDUwMDApCgpGX3IgPC0gZGVuc2l0eShzdGF0cykKCnBsb3RfZGYgPC0gZGF0YS5mcmFtZSgKICB0ID0gRl9yJHgsCiAgUl9kZW5zaXR5ID0gRl9yJHkKKQoKa2RlX3BsdCA8LSBnZ3Bsb3QocGxvdF9kZiwgYWVzKHggPSB0LCB5ID0gUl9kZW5zaXR5KSkgKwogIGdlb21fbGluZShsaW5ld2lkdGggPSAxKSArCiAgbGFicygKICAgIHRpdGxlID0gIkJvb3RzdHJhcCBTYW1wbGUgVmFyaWFuY2UgS0RFIiwKICAgIHggPSAidCIsCiAgICB5ID0gIkRlbnNpdHkiCiAgKSArCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpCgpnZ3Bsb3RseShrZGVfcGx0KQpgYGAKVGhlIEtERSBvZiB0aGUgYm9vdHN0cmFwIHNhbXBsZSB2YXJpYW5jZXMgYXBwZWFycyBzeW1tZXRyaWMgYW5kIHVuaS1tb2RhbCwgc3VnZ2VzdGluZyB0aGF0IHRoZSBzYW1wbGluZyBkaXN0cmlidXRpb24gb2YgdGhlIHZhcmlhbmNlIGlzIGFwcHJveGltYXRlbHkgbm9ybWFsLiBUaGVyZWZvcmUsIHVzaW5nIHRoZSBDZW50cmFsIExpbWl0IFRoZW9yZW0gdG8gZGVyaXZlIHRoZSBhc3ltcHRvdGljIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiBvZiB0aGUgc2FtcGxlIHZhcmlhbmNlIHdvdWxkJ3ZlIGJlZW4gYWNjZXB0YWJsZS4=